package utils;


import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONObject;
import contants.CommonConstant;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author ccc
 * @create 2021-04-21 16:04
 */
public class HttpClientUtil {

    public static String doGetByCookie(String url, Map<String, String> param, Map<String, String> cookieParam) {

        CloseableHttpClient httpClient = null;
//        if (cookieParam == null) {
        //创建Httpclient对象
        httpClient = HttpClients.createDefault();
//        } else {
//            //获取cookie
//            CookieStore cookieStore = setCookieByMap(cookieParam);
//
//            httpClient = HttpClients.custom()
//                    .setDefaultCookieStore(cookieStore)
//                    .build();
//        }
        //设置 HttpClient 接收 Cookie,用与浏览器一样的策略
        // 设置cookies信息
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            //设置getHeader请求头
            if (cookieParam != null) {
                addHttpGetHeaderByCookie(cookieParam, httpGet);
            }
            // 执行请求
            response = httpClient.execute(httpGet);

            // 读取cookie信息
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), getDefaultCharSet());
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String doGetByRoute(String url, Map<String, String> param,Map<String, String> cookieParam) {
        //设置cookie
        CookieStore cookieStore = setCookieByMap(cookieParam);

        // 创建Httpclient对象
//        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpClient httpclient = HttpClients.custom()
                .setDefaultCookieStore(cookieStore)
                .build();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {

            if (param != null) {
                for (String key : param.keySet()) {
                    url = url+"/"+param.get(key);
                }
            }
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            //设置getHeader请求头
            addHttpGetHeader(cookieParam, httpGet);
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), getDefaultCharSet());
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }
    /**
     * 发送get请求
     *
     * @param url   请求地址
     * @param param 参数
     * @return
     */
    public static String doGet(String url, Map<String, String> param,Map<String, String> cookieParam) {

        CloseableHttpClient httpClient = null;
        if (cookieParam == null){
            //创建Httpclient对象
            httpClient = HttpClients.createDefault();
        }else {
            //获取cookie
            CookieStore cookieStore = setCookieByMap(cookieParam);

            httpClient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore)
                    .build();
        }
        //设置 HttpClient 接收 Cookie,用与浏览器一样的策略
        // 设置cookies信息
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);
            //设置getHeader请求头
            if (cookieParam!=null){
                addHttpGetHeader(cookieParam, httpGet);
            }
            // 执行请求
            response = httpClient.execute(httpGet);

            // 读取cookie信息
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), getDefaultCharSet());
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    /**
     * 发送get请求，不带参数
     *
     * @return
     */
    public static String doGet(String url) {
        return doGet(url, null,null);
    }

    /**
     * 发送POST请求，携带map格式的参数
     * 如：name="jok",age="10"
     *
     * @param url   请求地址
     * @param param Map格式的参数
     * @return
     */
    public static String doPost(String url, Map<String, String> param,Map<String, String> cookieParam) {
        //获取cookie
        CookieStore cookieStore = setCookieByMap(cookieParam);
        // 创建Httpclient对象
//        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCookieStore(cookieStore)
                .build();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {

            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            //设置HttpPost请求头参数
            if (cookieParam != null){
                httpPost.addHeader(CommonConstant.X_ACCESS_TOKEN, cookieParam.get("token"));
                httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
            }
            //httpPost.addHeader(CommonConstant.TOKEN, cookieParam.get("token"));
            //httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, getDefaultCharSet());
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), getDefaultCharSet());
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response!=null){
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }

    /**
     * 发送POST请求，不带参数
     *
     * @param url 请求地址
     * @return
     */
    public static String odoPost(String url) {
        return doPost(url, null,null);
    }

    /**
     * 发送post请求，携带json类型数据
     * 如：{"name":"jok","age":"10"}
     *
     * @param url  请求地址
     * @param json json格式参数
     * @return
     */
    public static String doPostJson(String url, String json,Map<String, String> cookieParam) {
        // 创建Httpclient对象
//        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = null;
//        if (cookieParam == null){
        //创建Httpclient对象
        httpClient = HttpClients.createDefault();
//        }else {
        //获取cookie
//            CookieStore cookieStore = setCookieByMap(cookieParam);

//            httpClient = HttpClients.custom()
//                    .setDefaultCookieStore(cookieStore)
//                    .build();
//        }

        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            //设置HttpPost请求头参数
            if (cookieParam != null){
                addHttpPostHeader(cookieParam, httpPost);
            }
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), getDefaultCharSet());
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response!=null){
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }


    public static String doDeleteByRoute(String url, Map<String, String> param,Map<String, String> cookieParam) {
        //获取cookie
        CookieStore cookieStore = setCookieByMap(cookieParam);
        // 创建Httpclient对象
//        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCookieStore(cookieStore)
                .build();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {

            if (param != null) {
                for (String key : param.keySet()) {
                    url = url+"/"+param.get(key);
                }
            }
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            URI uri = builder.build();
            // 创建Http Delete请求
            HttpDelete httpDelete = new HttpDelete(uri);

            //设置delete的请求头参数
            addHttpDeleteHeader(cookieParam, httpDelete);
            // 执行http请求
            response = httpClient.execute(httpDelete);
            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {

            }
        }
        return resultString;
    }

    public static String doDelete(String url, Map<String, String> param,Map<String, String> cookieParam) {
        CloseableHttpClient httpClient = null;
        if (cookieParam == null){
            // 创建Httpclient对象
            httpClient = HttpClients.createDefault();
        } else {
            //获取cookie
            CookieStore cookieStore = setCookieByMap(cookieParam);

            httpClient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore)
                    .build();
        }

        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建Http Delete请求
            HttpDelete httpDelete = new HttpDelete(uri);
            //设置delete的请求头参数
            addHttpDeleteHeader(cookieParam, httpDelete);
            // 执行http请求
            response = httpClient.execute(httpDelete);
            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response!=null){
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {

            }
        }

        return resultString;
    }

    public static String doPostJsonByCookie(String url, String json, Map<String, String> cookieParam) {
        // 创建Httpclient对象
//        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = null;
//        if (cookieParam == null){
        //创建Httpclient对象
        httpClient = HttpClients.createDefault();
//        }else {
        //获取cookie
//            CookieStore cookieStore = setCookieByMap(cookieParam);

//            httpClient = HttpClients.custom()
//                    .setDefaultCookieStore(cookieStore)
//                    .build();
//        }

        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            //设置HttpPost请求头参数
            if (cookieParam != null) {
                addHttpPostHeaderByCookie(cookieParam, httpPost);
            }
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), getDefaultCharSet());
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    /**
     * 设置编码格式utf-8,防止乱码
     *
     * @return utf-8
     */
    private static String getDefaultCharSet() {
        OutputStreamWriter writer = new OutputStreamWriter(new ByteArrayOutputStream());
        String enc = writer.getEncoding();
        return enc;
    }

    public static String doPutJson(String url, String json,Map<String, String> cookieParam) {
        // 创建Httpclient对象
//        CloseableHttpClient httpClient = HttpClients.createDefault();
        //获取cookie
        CookieStore cookieStore = setCookieByMap(cookieParam);
        // 创建Httpclient对象
//        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCookieStore(cookieStore)
                .build();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Put请求
            HttpPut httpPut = new HttpPut(url);
            //设置HttpPost请求头参数
            if (cookieParam != null){
                addHttpPutHeader(cookieParam, httpPut);
            }
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPut.setEntity(entity);
            // 执行http请求
            response = httpClient.execute(httpPut);
            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            resultString = JSONObject.toJSONString(Result.error("connection time out!"));
            return resultString;
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpClient.close();
            } catch (IOException e) {

            }
        }

        return resultString;
    }

    //通过传过来的param设置cookie值，解决httpClient调用获取不到cookie方法
    //采用在调用前在param传cookiename和value值的方式
    private static CookieStore setCookieByMap(Map<String, String> param) {
        CookieStore cookieStore = new BasicCookieStore();
//        if(oConvertUtils.isNotEmpty(param)) {
        if(MapUtil.isNotEmpty(param)){
            BasicClientCookie cookie = new BasicClientCookie("token", param.get("token"));
            cookie.setSecure(false);
            //=cookie.setDomain(".dyw.com");
            //=cookie.setAttribute("domain",".dyw.com");
            //没域名前使用ip当域名 仅限认证中心和中心系统,因为他们两是在同一ip不同端口
            cookie.setDomain("172.16.1.47");
//            cookie.setDomain("172.16.1.183");
//            cookie.setDomain("120.234.215.109");
//            cookie.setDomain("172.16.1.13");
//            cookie.setDomain("172.16.1.207");
            cookie.setAttribute("domain", "172.16.1.47");
//            cookie.setAttribute("domain", "172.16.1.183");
//            cookie.setAttribute("domain", "120.234.215.109");
//            cookie.setAttribute("domain", "172.16.1.13");
//            cookie.setAttribute("domain", "172.16.1.207");
            cookie.setPath("/");
            cookieStore.addCookie(cookie);
        }
        return cookieStore;
    }

    /**
     * 设置HttpGet请求头参数
     */
    private static void addHttpGetHeader(Map<String, String> cookieParam, HttpGet httpGet) {
        //设置请求头参数
        httpGet.addHeader(CommonConstant.TOKEN, cookieParam.get("token"));
        httpGet.addHeader("Authorization", cookieParam.get("Authorization"));
        httpGet.addHeader("Content-Type", "application/json;charset=UTF-8");
    }

    /**
     * 设置HttpPost请求头参数
     */
    private static void addHttpPostHeader(Map<String, String> cookieParam, HttpPost httpPost) {
        httpPost.addHeader(CommonConstant.TOKEN, cookieParam.get("token"));
        httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
    }

    /**
     * 设置HttpPut请求头参数
     */
    private static void addHttpPutHeader(Map<String, String> cookieParam, HttpPut httpPut) {
        httpPut.addHeader(CommonConstant.TOKEN,cookieParam.get("token"));
        httpPut.addHeader("Content-Type","application/json;charset=UTF-8");
    }

    private static void addHttpPostHeaderByCookie(Map<String, String> cookieParam, HttpPost httpPost) {
        httpPost.addHeader(CommonConstant.TOKEN, cookieParam.get("token"));
        httpPost.addHeader("Cookie","token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZXMiOiJ6dGNhZG1pbiIsInN1YiI6InVzZXIiLCJleHAiOjE2NjcxOTY4MTQsImp0aSI6IjBmMzljMjU0LWJkMmUtNGY1OC05NThhLWU5OGZlYzVmYjBjMCJ9.Zb55CKoFgXvYcYHlwNJPV5R8fforod1_EsNuiHVZQKw");
        httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
    }

    private static void addHttpGetHeaderByCookie(Map<String, String> cookieParam, HttpGet httpGet) {
        //设置请求头参数
        httpGet.addHeader(CommonConstant.TOKEN, cookieParam.get("token"));
        httpGet.addHeader("Cookie","token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyZXMiOiJ6dGNhZG1pbiIsInN1YiI6InVzZXIiLCJleHAiOjE2NjcxOTY4MTQsImp0aSI6IjBmMzljMjU0LWJkMmUtNGY1OC05NThhLWU5OGZlYzVmYjBjMCJ9.Zb55CKoFgXvYcYHlwNJPV5R8fforod1_EsNuiHVZQKw");
        httpGet.addHeader("Content-Type", "application/json;charset=UTF-8");
    }

    /**
     * 设置HttpDelete请求头参数
     */
    private static void addHttpDeleteHeader(Map<String, String> cookieParam, HttpDelete httpDelete) {
        httpDelete.addHeader(CommonConstant.TOKEN, cookieParam.get("token"));
        httpDelete.addHeader("Content-Type", "application/json;charset=UTF-8");
    }

}
